package queue.model;

import distributions.ExponentialStream;
import distributions.UniformStream;
import java.io.IOException;
import java.util.Observer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author mostafa
 */
public class MachineCenter extends InspectionStation {

    private ExponentialStream breakDownDist;
    private UniformStream fixingDist;
    private long remainingTimeMillis;
    private boolean broken;

    public MachineCenter(String name, Observer observer) {
        super(name, observer);
        breakDownDist = new ExponentialStream(3);
        fixingDist = new UniformStream(0.8, 1.2);
        broken = false;
        scheduleBreakDown();
    }

    private void scheduleBreakDown() {
        try {
            timer.schedule(new MachineCenterBreak(), (long) (TIME_TRANSLATION_CONST * breakDownDist.getNumber()));
        } catch (IOException ex) {
            Logger.getLogger(MachineCenter.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ArithmeticException ex) {
            Logger.getLogger(MachineCenter.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    private void scheduleFix() {
        try {
            timer.schedule(new MachineCenterFix(), (long) (TIME_TRANSLATION_CONST * fixingDist.getNumber()));
        } catch (IOException ex) {
            Logger.getLogger(MachineCenter.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ArithmeticException ex) {
            Logger.getLogger(MachineCenter.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    protected boolean serverAvaiavble() {
        return super.serverAvaiavble() && ! broken;
    }

    private class MachineCenterFix extends TimerTask {
        // now fixed
        @Override
        public void run() {
            broken = false;
            System.out.println("Machine Fixed and ");
            if (currentItem != null) {
                System.out.println("remaining time is " + remainingTimeMillis);
                ItemDeparture departure = new ItemDeparture(currentItem);
                currentItem.setDeparture(departure);
                timer.schedule(departure, remainingTimeMillis);
            }else
                System.out.println("idle");
            scheduleBreakDown();
        }
    }

    private class MachineCenterBreak extends TimerTask {
        // now broken down
        @Override
        public void run() {
            System.out.println("Machine broke down when ");
            if (currentItem != null) {
                remainingTimeMillis = Math.max(0, currentItem.getDeparture().scheduledExecutionTime()
                        - System.currentTimeMillis());
                System.out.println("RemainingTimeMillis: " + remainingTimeMillis);
                System.out.println("Serving " + currentItem + "\tremaining time:"
                        + "\t" + remainingTimeMillis);
                currentItem.getDeparture().cancel();
            }else
                System.out.println(" Idle");
            broken = true;
            scheduleFix();
        }
    }
}
